package org.crown.project.api.utils;

import cn.hutool.core.util.StrUtil;
import org.crown.common.utils.Md5Utils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * 讯付通-签名
 *
 * @author Mr.C
 * @date 2018/10/29
 */
public class SignUtil {

    /**
     * 拼装参数
     */
    public synchronized static String createLinkString(Map<String, String> params, boolean isIgnoreNullValue, String... ignoreKeys) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        StringBuilder data = new StringBuilder();
        for (String key : keys) {
            String value = params.get(key);
           /* if (isIgnoreNullValue && ("".equals(value) || value == null)) {
                continue;
            }*/
            if (ignoreKeys != null && ignoreKeys.length > 0) {
                boolean isIgnoreKey = false;
                for (String ignoreKey : ignoreKeys) {
                    if (key.equals(ignoreKey)) {
                        isIgnoreKey = true;
                        break;
                    }
                }
                if (isIgnoreKey) {
                    continue;
                }
            }
            data.append(key).append("=").append(value).append("&");
        }
        if (data.length() > 0) {
            data = data.deleteCharAt(data.length() - 1);
        }
        return data.toString();
    }

    /**
     * map转换url参数
     *
     * @param paramMap           param map
     * @param isIgnoreBlankValue is ignore null value
     * @param ignoreKeyArray     ignore key array
     * @return string
     * @author Lv ShuTing
     * @since creation time 2019-08-30 13:55:22
     */
    public synchronized static String mapToUrlParams(Map<String, String> paramMap, boolean isIgnoreBlankValue, String... ignoreKeyArray) {
        return mapSplice(paramMap, isIgnoreBlankValue, "=", "&", ignoreKeyArray);
    }

    /**
     * 无连接符参数拼接
     */
    public synchronized static String noConnectorMapSplice(Map<String, String> paramMap, boolean isIgnoreBlankValue, String... ignoreKeyArray) {
        return mapSplice(paramMap, isIgnoreBlankValue, null, null, ignoreKeyArray);
    }

    /**
     * map -> 键值对连接字符串.
     *
     * @param paramMap           param map
     * @param isIgnoreBlankValue is ignore blank value
     * @param separator          键值对分隔符
     * @param connector          键值对拼接连接符
     * @param ignoreKeyArray     ignore key array
     * @return string
     * @author Lv ShuTing
     * @since creation time 2019-11-20 09:37:25
     */
    public synchronized static String mapSplice(Map<String, String> paramMap, boolean isIgnoreBlankValue, String separator, String connector, String... ignoreKeyArray) {
        if (null == paramMap || paramMap.isEmpty()) {
            return null;
        }

        Map<String, String> paramMapClone = new HashMap<>(16);
        paramMapClone.putAll(paramMap);
        for (String ignoreKey : ignoreKeyArray) {
            paramMapClone.remove(ignoreKey);
        }

        // ASCII码从小到大排序（字典序）
        List<String> keys = new ArrayList<>(paramMapClone.keySet());
        Collections.sort(keys);

        // 参数拼接成字符串（例：字段1=xxx&字段2=yyy）
        StringBuilder paramSb = new StringBuilder();
        for (String key : keys) {
            String value = paramMapClone.get(key);
            if (isIgnoreBlankValue && StrUtil.isBlank(value)) {
                continue;
            }
            paramSb.append(key).append(StrUtil.blankToDefault(separator, "")).append(value).append(StrUtil.blankToDefault(connector, ""));
        }

        if (0 == paramSb.length()) {
            return null;
        }

        if (!StrUtil.isBlank(connector)) {
            return paramSb.deleteCharAt(paramSb.length() - connector.length()).toString();
        }
        return paramSb.toString();
    }

    public static String createLinkEncodingString(Map<String, String> params, boolean isIgnoreNullValue, String... ignoreKeys) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        StringBuilder data = new StringBuilder();
        for (String key : keys) {
            String value = params.get(key);
            if (isIgnoreNullValue && ("".equals(value) || value == null)) {
                continue;
            }
            if (ignoreKeys != null && ignoreKeys.length > 0) {
                boolean isIgnoreKey = false;
                for (String ignoreKey : ignoreKeys) {
                    if (key.equals(ignoreKey)) {
                        isIgnoreKey = true;
                        break;
                    }
                }
                if (isIgnoreKey) {
                    continue;
                }
            }
            try {
                data.append(key).append("=").append(URLEncoder.encode(value, "utf-8")).append("&");
            } catch (UnsupportedEncodingException e) {
            }
        }
        if (data.length() > 0) {
            data = data.deleteCharAt(data.length() - 1);
        }
        return data.toString();
    }

    public static Map<String, String> linkString2Map(String linkString) {
        Map<String, String> params = new HashMap<String, String>();

        String[] ps = linkString.split("&");
        for (String p : ps) {
            String[] pt = p.split("=");
            if (pt.length == 2) {
                params.put(pt[0], pt[1]);
            }
        }
        return params;
    }


    public static String buildMD5SignData(Map<String, String> requestParams, boolean isIgnoreNullValue, String... ignoreKeys) {
        String linkString = createLinkString(requestParams, isIgnoreNullValue, ignoreKeys);
        return Md5Utils.hash(linkString);
    }

}
